package com.cy.mall.web.front.order;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.cy.mall.comm.constant.Constants;
import com.cy.mall.comm.utils.CommonUtils;
import com.cy.mall.comm.utils.JsonObjectMapper;
import com.cy.mall.comm.utils.RSAUtils;
import com.cy.mall.model.PageBean;
import com.cy.mall.model.ao.order.*;
import com.cy.mall.model.domain.order.OrderGoodsExtraInfo;
import com.cy.mall.model.dto.fujue.req.AddAttachmentParamDTO;
import com.cy.mall.model.dto.fujue.req.GetH5AddressParamDTO;
import com.cy.mall.model.dto.fujue.req.GetH5UrlParamDTO;
import com.cy.mall.model.enums.ResultCode;
import com.cy.mall.model.enums.fujue.AttachmentAddType;
import com.cy.mall.model.enums.fujue.FujueH5Type;
import com.cy.mall.model.enums.order.OrderFinalStatusE;
import com.cy.mall.model.enums.order.OrderImageType;
import com.cy.mall.model.query.order.OrderListQuery;
import com.cy.mall.model.vo.order.*;
import com.cy.mall.service.comm.FileUploadService;
import com.cy.mall.service.fujue.FujueApiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.cy.mall.model.Result;
import com.cy.mall.model.dto.bigdata.BigDataCheckParamDTO;
import com.cy.mall.model.dto.customer.CustomerLoginDTO;
import com.cy.mall.model.dto.customer.ValidateBigDataResultDTO;
import com.cy.mall.model.enums.CheckResult;
import com.cy.mall.service.comm.BigDataService;
import com.cy.mall.service.customer.CustomerService;
import com.cy.mall.service.order.OrderService;
import com.cy.mall.web.BaseController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.multipart.MultipartFile;

/**
 * 前台-订单
 *
 * @author tanyilin
 *
 * @create 2019年2月26日 上午9:57:17
 */
@Slf4j
@RestController
@RequestMapping("/customer/order")
@Api(tags = "前台-订单")
public class OrderController extends BaseController {

	@Autowired
	private OrderService      orderService;
	@Autowired
	private CustomerService   customerService;
	@Autowired
	private BigDataService    bigDataService;
	@Autowired
	private FujueApiService   fujueApiService;
	@Autowired
	private FileUploadService fileUploadService;
	
	@ApiOperation("新增订单(暂废弃)")
	@PostMapping("/do/add1")
	public Result doAddOrder(@RequestBody @Validated OrderAddAO addAO, BindingResult bindingResult) {
		
		this.checkError(bindingResult);
		CustomerLoginDTO loginCustomer = this.getLoginCustomer();
		//新增订单
		Result addOrderResult = orderService.addOrder(addAO, loginCustomer);
		Long orderId = (Long) addOrderResult.getData();
		Long customerId = loginCustomer.getCustomerId();
		
		//查询客户大数据是否通过
		ValidateBigDataResultDTO validateBigDataResultDTO = customerService.validateBigDataResult(customerId);
		//情况1：如果大数据查询过了，并且结果=不通过
		if(CheckResult.NOT_PASS.equals(validateBigDataResultDTO.getBigDataCheckResult())) {
			return ok("新增订单成功，但客户大数据查询结果不通过", ResultCode.ADD_ORDER_SUCCESS_BIGDATA_FAIL, orderId);
		}
		//情况2：如果未check,就去check
		if(CheckResult.UNCHECKED.equals(validateBigDataResultDTO.getBigDataCheckResult())) {
			
			//封装查询参数
			BigDataCheckParamDTO paramDTO = new BigDataCheckParamDTO();
			paramDTO.setName(validateBigDataResultDTO.getCustomerName());
			paramDTO.setIdCard(validateBigDataResultDTO.getIdNo());
			paramDTO.setMobile(validateBigDataResultDTO.getMobile());
			//查询客户大数据
			Result bigDataCheckResult = bigDataService.check(paramDTO);
			if(!bigDataCheckResult.isOk()) {
				//请求大数据查询失败，但是还是返回保存新增订单成功的信息
				return ok("新增订单成功", orderId);
			}
			
			//请求大数据查询成功，根据风控规则判断客户是否通过，并更新客户大数据查询结果信息表
			Map<String, Object> dataMap = (Map) bigDataCheckResult.getData();
			Result judgeResult = customerService.judgeBigDataCheckResult(dataMap, customerId);
			if(!judgeResult.isOk()) {
				return ok("新增订单成功，但客户大数据查询结果判定为：不通过", ResultCode.ADD_ORDER_SUCCESS_BIGDATA_FAIL, orderId);
			}
		}
		
		return ok("新增订单成功", orderId);
	}
	
	@ApiOperation("保存编辑订单(暂废弃)")
	@PostMapping("/do/edit1")
	public Result doEditOrder(@RequestBody @Validated OrderEditAO editAO, BindingResult bindingResult) {
		
		this.checkError(bindingResult);
		CustomerLoginDTO loginCustomer = this.getLoginCustomer();
		//查询客户大数据是否通过
		ValidateBigDataResultDTO validateBigDataResultDTO = customerService.validateBigDataResult(loginCustomer.getCustomerId());
		if(CheckResult.NOT_PASS.equals(validateBigDataResultDTO.getBigDataCheckResult())) {
			return ok("", ResultCode.ADD_ORDER_SUCCESS_BIGDATA_FAIL, editAO.getOrderId());
		}

		//保存编辑
		Result result = orderService.editOrder(editAO, loginCustomer);
		
		return result;
	}
	
	@ApiOperation("获取订单回显信息(暂废弃)")
	@GetMapping("/get/display/info1")
	public Result<OrderAddInfoDisplayVO> getOrderDisplayInfo(@RequestParam(value = "orderId") Long orderId) {
		
		OrderAddInfoDisplayVO orderAddInfoDisplayVO = orderService.getOrderDisplayInfo(orderId);
		
		return ok("", orderAddInfoDisplayVO);
	}
	
	@ApiOperation("订单列表")
	@GetMapping("/list")
	public PageBean<OrderListVO> orderList(OrderListQuery query) {
		query.setCustomerId(this.getLoginCustomer().getCustomerId());
		PageBean<OrderListVO> pageBean = orderService.selectOrderList(query);
		return pageBean;
	}

	@ApiOperation("订单详情")
	@GetMapping("/detail")
	public Result<OrderDetailVO> detail(@RequestParam(value = "orderId") Long orderId) {

		OrderDetailVO result = orderService.selectOrderDetailVO(orderId);

		return ok("", result);
	}

	@ApiOperation("获取富爵h5地址")
	@GetMapping("/get/fj/h5/address")
	public Result getFjH5Address(@Validated ApplyAmountAO applyAmountAO, BindingResult bindingResult) {

		this.checkError(bindingResult);
		CustomerLoginDTO loginCustomer = this.getLoginCustomer();

		GetH5AddressParamDTO paramDTO = new GetH5AddressParamDTO();
		BeanUtils.copyProperties(applyAmountAO, paramDTO);
		paramDTO.setMobileNo(loginCustomer.getMobile());
		paramDTO.setUserId(String.valueOf(loginCustomer.getCustomerId()));

		Result<Map<String, Object>> result = fujueApiService.getH5Address(paramDTO);
		return result;
	}

	@ApiOperation("商城首页获取已登录客户最近的一个订单信息")
	@GetMapping("/get/thelast/order/info")
	public Result getTheLastOrderInfo() {

		OrderListQuery query = new OrderListQuery();
		query.setPage(1);
		query.setLimit(100);
		PageBean<OrderListVO> pageBean = orderList(query);
		List<OrderListVO> list = pageBean.getData();
		if(CommonUtils.isEmpty(list)) {
			return ok("获取成功，但无数据");
		}
		//家易贷
		List<OrderListVO> jydlist = list.stream().filter(o -> Constants.JYD_PRODUCTID.equals(o.getProductId()))
							.collect(Collectors.toList());
		//嘻唰唰
		List<OrderListVO> xsslist = list.stream().filter(o -> Constants.XSS_PRODUCTID.equals(o.getProductId()))
				.collect(Collectors.toList());
		//薪享事成
		List<OrderListVO> xxsclist = list.stream().filter(o -> Constants.XXSC_PRODUCTID.equals(o.getProductId()))
				.collect(Collectors.toList());

		Map<String, Object> map = new HashMap<>();
		map.put("jyd", CommonUtils.isEmpty(jydlist) ? new OrderListVO() : jydlist.get(0));
		map.put("xss", CommonUtils.isEmpty(xsslist) ? new OrderListVO() : xsslist.get(0));
		map.put("xxsc", CommonUtils.isEmpty(xxsclist) ? new OrderListVO() : xxsclist.get(0));

		return ok("获取成功", map);
	}

	@ApiOperation("立即使用-填写家具订单信息")
	@PostMapping("/save/goods/order/extra/info")
	public Result saveOrderGoodsExtraInfo(@RequestBody @Validated OrderGoodsExtraInfoSaveAO saveAO, BindingResult bindingResult) {

		this.checkError(bindingResult);

		orderService.saveOrderGoodsExtraInfo(saveAO);

		return ok();
	}

	@ApiOperation("家易贷：确认申请信息并提交，生成订单")
	@PostMapping("/do/confirm/submit")
	public Result doConfirmSubmitOrder(@Validated ConfirmSubmitOrderAO confirmSubmitOrderAO, BindingResult bindingResult) {

		this.checkError(bindingResult);

		Result result = orderService.doConfirmSubmitOrder(confirmSubmitOrderAO, this.getLoginCustomer().getCustomerId());

		return result;
	}

	@ApiOperation("上传图片资料")
	@PostMapping("/upload/image")
	public Result uploadImage(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "orderId") Long orderId) {
		//上传至oss服务器
		String directory = "attachment/order/" + orderId + "/";
		Result<Map<String, String>> uploadResult = fileUploadService.uploadImage(file, directory, null);
		return uploadResult;
	}

	@ApiOperation("查询 订单补充资料上传状态")
	@GetMapping("/query/image/upload/status")
	public Result<OrderImageUploadStatusVO> queryOrderImageUploadStatus(@RequestParam(value = "orderId") Long orderId) {

		OrderImageUploadStatusVO statusVO = orderService.queryOrderImageUploadStatus(orderId);

		return ok("查询成功", statusVO);
	}

	@ApiOperation("获取订单图片（文件）资料列表")
	@GetMapping("/get/image/list")
	public Result<List<OrderImageListVO>> getOrderImageList(@RequestParam(value = "orderId") Long orderId,
					@RequestParam(value = "orderImageType") OrderImageType orderImageType) {

		List<OrderImageListVO> list = orderService.getOrderImageList(orderId, orderImageType);
		return ok("获取成功", list);
	}

	@ApiOperation("保存订单图片（文件）资料")
	@PostMapping("/do/save/image/list")
	public Result doSaveOrderImage(@RequestBody @Validated OrderImageSaveAO saveAO, BindingResult bindingResult) {

		this.checkError(bindingResult);

		orderService.doSaveOrderImage(saveAO);

		return ok("保存图片资料成功");
	}

	@ApiOperation("提交补充资料")
	@PostMapping("/do/add/attachment")
	public Result doAddAttachment(@RequestParam(value = "orderId") Long orderId) {

		OrderGoodsExtraInfo dbOrderGoodsExtraInfo = orderService.getOrderGoodsExtraInfoByOrderId(orderId);
		if(OrderFinalStatusE.MATERIAL_AUDITING.equals(dbOrderGoodsExtraInfo.getFinalStatus())) {
			return fail("订单已经提交过补充资料，请勿重复提交。");
		}

		//查询请求参数
		AddAttachmentParamDTO paramDTO = orderService.getAddAttachmentParam(orderId);
		paramDTO.setAddType(AttachmentAddType.NORMAL.getValue());
		//调用api
		Result<Map<String, Object>> result = fujueApiService.addAttachment(paramDTO);
		if(!result.isOk()) {
			return result;
		}
		//对返回数据进行 RSA解密
		Map<String, Object> bodyMap = result.getData();
		String encryptData = String.valueOf(bodyMap.get("data"));
		log.info("提交补充资料 api，返回参数data密文：{}", encryptData);
		String decryptData = RSAUtils.privateDecrypt(encryptData, Constants.FUJUE_RSA_PRIVATE_KEY);
		log.info("提交补充资料 api，返回参数data明文：{}", decryptData);
		//解析data
		Map<String, Object> dataMap = JsonObjectMapper.read(decryptData, Map.class);

		//更新订单最终状态
		orderService.updateOrderFinalStatus(orderId, OrderFinalStatusE.MATERIAL_AUDITING);

		return ok("订单提交补充资料成功", dataMap);
	}

	@ApiOperation("请求云科签约、还款h5页面url")
	@GetMapping("/get/fj/h5/url")
	public Result getH5Url(@RequestParam(value = "loanId") String loanId, @RequestParam(value = "h5Type") FujueH5Type h5Type) {

		//封装请求参数
		GetH5UrlParamDTO getH5UrlParamDTO = new GetH5UrlParamDTO();
		getH5UrlParamDTO.setLoanId(loanId);
		getH5UrlParamDTO.setH5Type(h5Type.getValue());

		//调用api
		Result<Map<String, Object>> result = fujueApiService.getH5Url(getH5UrlParamDTO);
		if(!result.isOk()) {
			return result;
		}
		//对返回数据进行 RSA解密
		Map<String, Object> bodyMap = result.getData();
		String encryptData = String.valueOf(bodyMap.get("data"));
		log.info("获取签约、还款h5页面 api，返回参数data密文：{}", encryptData);
		String decryptData = RSAUtils.privateDecrypt(encryptData, Constants.FUJUE_RSA_PRIVATE_KEY);
		log.info("获取签约、还款h5页面 api，返回参数data明文：{}", decryptData);
		//解析data
		Map<String, Object> dataMap = JsonObjectMapper.read(decryptData, Map.class);

		return ok("获取h5Url成功", dataMap);
	}

}
